package com.sbtr.common.auto;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.sbtr.controller.common.CommonController;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 功能描述: 代码生成器
 *
 * @author dgl
 * @date 2020/10/16 16:00
 */
public class AutoGenerateCode {

    private final static String projectPath = System.getProperty("user.dir");

    public static void generateCode(GennerateCodeDTO gennerateCodeDTO) throws InterruptedException {
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
//        gc.setOutputDir(projectPath + gennerateCodeDTO.getOutputDir());

        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");

        gc.setOpen(true);//是否打开
        gc.setFileOverride(false); //是否覆盖
        gc.setActiveRecord(true);
        gc.setEnableCache(false);// XML 二级缓存
        gc.setBaseResultMap(true);// XML ResultMap
        gc.setBaseColumnList(true);// XML columList
        gc.setAuthor(gennerateCodeDTO.getAuthor());
        gc.setDateType(DateType.ONLY_DATE);
        gc.setSwagger2(true);
        gc.setIdType(IdType.AUTO);

        // 自定义文件命名，注意 %s 会自动填充表实体属性！
        gc.setMapperName("%sMapper");
        gc.setXmlName("%sMapper");
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sServiceImpl");
        gc.setControllerName("%sController");

        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUrl(gennerateCodeDTO.getUrl());
        dsc.setUsername(gennerateCodeDTO.getUsername());
        dsc.setPassword(gennerateCodeDTO.getPassword());
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent(gennerateCodeDTO.getParentDir());
        pc.setController("controller");
        pc.setEntity("entity");
        pc.setMapper("mapper");
        pc.setModuleName(gennerateCodeDTO.getModelName());
        mpg.setPackageInfo(pc);


        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> objectMap = new HashMap<>();
//                objectMap.put("controllerPackage", gennerateCodeDTO.getParentDir() + "." + gennerateCodeDTO.getTerminal() + "." + gennerateCodeDTO.getModelName());
                objectMap.put("controllerPackage", gennerateCodeDTO.getParentDir()+"." + gennerateCodeDTO.getModelName());
//                objectMap.put("controllerNamePrefix", gennerateCodeDTO.getTerminal().substring(0, 1).toUpperCase() + gennerateCodeDTO.getTerminal().substring(1));
                objectMap.put("controllerNamePrefix","");
                objectMap.put("terminal", gennerateCodeDTO.getTerminal());
                objectMap.put("instanceOf", new InstanceOfMethod());
                objectMap.put("usePrefix", gennerateCodeDTO.isUsePrefix());
                this.setMap(objectMap);
            }
        };

        List<FileOutConfig> focList = new ArrayList<>();

        focList.add(new FileOutConfig("/generate/controller.java.ftl") {

            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
//                return projectPath + gennerateCodeDTO.getOutputDir() + "/" + gennerateCodeDTO.getParentDir().replace(".", "/") + "/" + gennerateCodeDTO.getTerminal() + "/" + gennerateCodeDTO.getModelName() + "/"
//                        + gennerateCodeDTO.getTerminal().substring(0, 1).toUpperCase() + gennerateCodeDTO.getTerminal().substring(1) + tableInfo.getControllerName() + StringPool.DOT_JAVA;
                return projectPath + gennerateCodeDTO.getOutputDir() + "/" + gennerateCodeDTO.getParentDir().replace(".", "/") + "/" + gennerateCodeDTO.getTerminal() + "/" + gennerateCodeDTO.getModelName() + "/"
                        + tableInfo.getControllerName() + StringPool.DOT_JAVA;
            }
        });

        focList.add(new FileOutConfig("/generate/entityDto.java.ftl") {

            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
//                return projectPath + gennerateCodeDTO.getOutputDir() + "/" + gennerateCodeDTO.getParentDir().replace(".", "/") + "/" + gennerateCodeDTO.getTerminal() + "/" + gennerateCodeDTO.getModelName() + "/"
//                        + gennerateCodeDTO.getTerminal().substring(0, 1).toUpperCase() + gennerateCodeDTO.getTerminal().substring(1) + tableInfo.getControllerName() + StringPool.DOT_JAVA;
                return projectPath + gennerateCodeDTO.getOutputDir() + "/" + gennerateCodeDTO.getParentDir().replace(".", "/") + "/" + gennerateCodeDTO.getTerminal() + "/" + gennerateCodeDTO.getModelName() + "/dto/"
                        + tableInfo.getEntityName()+"Dto" + StringPool.DOT_JAVA;
            }
        });



        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        // 配置自定义输出模板
        //指定自定义模板路径，注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别

        templateConfig.setServiceImpl("/generate/serviceImpl.java");
        templateConfig.setService("/generate/service.java");
        templateConfig.setMapper("/generate/mapper.java");
        templateConfig.setEntity("/generate/entity.java");
        focList.add(new FileOutConfig("/generate/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return projectPath + gennerateCodeDTO.getMapperDir() + "/" + gennerateCodeDTO.getModelName() + "/"
                        + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        templateConfig.setXml(null);
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        templateConfig.setController(null);
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        //此处可以修改为您的表前缀
        strategy.setTablePrefix(gennerateCodeDTO.getTablePrefix());
        // 表名生成策略
        strategy.setNaming(NamingStrategy.underline_to_camel);
        // 需要生成的表
        strategy.setInclude(gennerateCodeDTO.getTableNames());
        // 排除生成的表
        //strategy.setExclude(new String[]{"test"});
        strategy.setEntityLombokModel(true);
        //生成rest 风格controller
        strategy.setRestControllerStyle(true);
        strategy.setSuperControllerClass("CommonController");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());

        // 执行生成
        mpg.execute();
    }


    /**
     * 执行主方法
     *
     * @param args
     */
    public static void main(String[] args) throws IOException {
        String[] tablesName = {"a_algo_predict_record"};
        String[] tablePrefix ={"a_"};
        String terminal = "";     //对应controller，不同端
        String author = "dgl";     //作者
        String modelName = "project";      //相应业务模块
        GennerateCodeDTO gennerateCodeDTO = new GennerateCodeDTO(tablesName, author, modelName, terminal,tablePrefix);
        try {
            generateCode(gennerateCodeDTO);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
